﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;

namespace iNet.Collections
{
	/// <summary>
	/// 泛型與非泛型清單的轉接介面。
	/// </summary>
	/// <typeparam name="T">清單的元素型別。</typeparam>
	public class TypedList<T> : IList<T>, INotifyCollectionChanged
	{
		#region 欄位
		readonly IList _InnerList;
		#endregion
		#region 建構子
		/// <summary>
		/// 初始化新的 TypedList 執行個體。
		/// </summary>
		/// <param name="list">IList 介面。</param>
		/// <exception cref="ArgumentNullException">list 為 Null (Visual Basic 為 Nothing)。</exception>
		public TypedList(IList list)
		{
			//確認參數
			if (list == null)
				throw new ArgumentNullException("list");

			//初始化欄位
			_InnerList = list;

			//事件連結
			INotifyCollectionChanged eventSource = (list as INotifyCollectionChanged);
			if (eventSource != null)
				eventSource.CollectionChanged += this.OnInnerCollectionChanged;
		}
		#endregion
		#region CollectionChanged
		/// <summary>
		/// 發生在集合改變後。
		/// </summary>
		public event NotifyCollectionChangedEventHandler CollectionChanged;
		#endregion
		#region IndexOf
		/// <summary>
		/// 取得列表中指定項目的索引值。
		/// </summary>
		/// <param name="item">指定的項目。</param>
		/// <returns>指定項目的索引值，-1 表示項目不在列表中。</returns>
		public int IndexOf(T item)
		{
			return _InnerList.IndexOf(item);
		}
		#endregion
		#region Insert
		/// <summary>
		/// 
		/// </summary>
		/// <param name="index"></param>
		/// <param name="item"></param>
		public void Insert(int index, T item)
		{
			_InnerList.Insert(index, item);
		}
		#endregion
		#region OnInnerCollectionChanged
		void OnInnerCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
		{
			if (this.CollectionChanged != null)
				this.CollectionChanged(this, e);
		}
		#endregion

		

		

		public void RemoveAt(int index)
		{
			_InnerList.RemoveAt(index);
		}

		public T this[int index]
		{
			get
			{
				return (T)_InnerList[index];
			}
			set
			{
				_InnerList[index] = value;
			}
		}

		public void Add(T item)
		{
			_InnerList.Add(item);
		}

		public void Clear()
		{
			_InnerList.Clear();
		}

		public bool Contains(T item)
		{
			return _InnerList.Contains(item);
		}

		public void CopyTo(T[] array, int arrayIndex)
		{
			_InnerList.CopyTo(array, arrayIndex);
		}

		public int Count
		{
			get 
			{
				return _InnerList.Count;
			}
		}

		public bool IsReadOnly
		{
			get 
			{
				return _InnerList.IsReadOnly;
			}
		}

		public bool Remove(T item)
		{
			int index = _InnerList.IndexOf(item);
			if (index >= 0)
			{
				_InnerList.RemoveAt(index);
				return true;
			}
			return false;
		}

		public IEnumerator<T> GetEnumerator()
		{
			return new Enumerator<T>(_InnerList.GetEnumerator());
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return _InnerList.GetEnumerator();
		}
	}
}
